@isTest
private class AccountLead_TestFieldSync {
	// Create a new Lead, Override Account Fields
	
	static testMethod void NewLeadOverride(){
		System.debug('************************************************************');
		Account TestAccount = new Account(Status__c = 'Targeted', Name = 'Test');
		insert TestAccount;
		Lead TestLead = new Lead(Account__c = TestAccount.Id, Company = 'Test', LastName='Smith',Override_Account_Fields__c = true,Status = 'Contacted');
		test.starttest();
		insert TestLead;
		test.stoptest();
		TestAccount = [select Status__c from Account where Id = :TestAccount.Id];
		System.AssertEquals('Contacted',TestAccount.Status__c);
		
	}
	
	// Create a new Lead, don't override Account fields
	static testMethod void NewLeadNoOverride(){
		Account TestAccount = new Account(Status__c = 'Targeted', Name = 'Test');
		insert TestAccount;
		Lead TestLead = new Lead(Account__c = TestAccount.Id, Company = 'Test', LastName='Smith',Status = 'Contacted');
		test.starttest();
		insert TestLead;
		test.stoptest();
		TestAccount = [select Status__c from Account where Id = :TestAccount.Id];
		System.Assert(TestAccount.Status__c == 'Targeted');
	}
	 
	// Update a Lead
	static testMethod void UpdateLead(){
		LeadSync_AsyncApex.firstTrigger = false; // Keep the triggers from starting future methods
		Account TestAccount = new Account(Status__c = 'Targeted', Name = 'Test');
		insert TestAccount;
		Lead TestLead = new Lead(Account__c = TestAccount.Id, Company = 'Test', LastName='Smith',Status = 'Targeted');
		insert TestLead;
		TestLead.Status='Contacted';
		test.starttest();
		LeadSync_AsyncApex.firstTrigger = true;
		update TestLead;
		test.stoptest();
		TestAccount = [select Status__c from Account where Id = :TestAccount.Id];
		System.Assert(TestAccount.Status__c == 'Contacted');
	}
	
	// Change Lead Account, override Account values
	static testMethod void UpdateLeadAccountOverride(){
		LeadSync_AsyncApex.firstTrigger = false; // Keep the triggers from starting future methods
		Account TestAccount = new Account(Status__c = 'Targeted', Name = 'Test');
		insert TestAccount;
		Lead TestLead = new Lead(Company = 'Test', LastName='Smith',Status = 'Targeted');
		insert TestLead;
		TestLead.Account__c = TestAccount.Id;
		TestLead.Override_Account_Fields__c = true;
		TestLead.Status = 'Contacted';
		test.starttest();
		LeadSync_AsyncApex.firstTrigger = true;
		update TestLead;
		test.stoptest();
		TestAccount = [select Status__c from Account where Id = :TestAccount.Id];
		System.Assert(TestAccount.Status__c == 'Contacted');
	}
	
	// Change Lead Account, don't override Account values
	static testMethod void UpdateLeadAccountNoOverride(){
		Account TestAccount = new Account(Status__c = 'Targeted', Name = 'Test');
		insert TestAccount;
		Lead TestLead = new Lead(Company = 'Testing', LastName='Smith',Status = 'Contacted');
		insert TestLead;
		TestLead.Account__c = TestAccount.Id;
		test.starttest();
		update TestLead;
		test.stoptest();
		TestLead = [select Status from Lead where Id = :TestLead.Id];
		System.AssertEquals('Targeted',TestLead.Status);
	}
	
	// Update an Account
	static testMethod void UpdateAccount(){
		LeadSync_AsyncApex.firstTrigger = false; // Keep the triggers from starting future methods
		Account TestAccount = new Account(Status__c = 'Targeted', Name = 'Test');
		insert TestAccount;
		Lead TestLead = new Lead(Account__c = TestAccount.Id, Company = 'Test', LastName='Smith',Status = 'Targeted');
		insert TestLead;
		TestAccount.Status__c='Contacted';
		test.starttest();
		LeadSync_AsyncApex.firstTrigger = true;
		update TestAccount;
		test.stoptest();
		TestLead = [select Status from Lead where Id = :TestLead.Id];
		System.Assert(TestLead.Status == 'Contacted');
	}
	
	static testMethod void FindAccountForLead(){
		Account TestAccount = new Account(Status__c = 'Targeted', Name = 'Test123456789');
		insert TestAccount;
		Lead TestLead = new Lead(Company = 'Test123456789', LastName='Smith',Status = 'Targeted');
		insert TestLead;
		
		TestLead = [select Account__c from Lead where Id = :TestLead.Id];
		System.AssertEquals(TestAccount.Id,TestLead.Account__c);
	}
	
	static testMethod void UpdateAccountWithManyLeads(){
		LeadSync_AsyncApex.firstTrigger = false; // Keep the triggers from starting future methods
		Account TestAccount = new Account(Status__c = 'Targeted', Name = 'Test');
		insert TestAccount;
		List<Lead> TestLeads = new List<Lead>();
		for(integer j = 0; j<3;j++){
			for(integer i=0;i<100;i++){
				TestLeads.add( new Lead(Account__c = TestAccount.Id, Company = 'Test', LastName='Test '+i ,Status = 'Targeted'));
			}
			insert TestLeads;
			TestLeads.clear();
		}
		TestAccount.Status__c = 'Contacted';
		test.starttest();
		LeadSync_AsyncApex.firstTrigger = true;
		update TestAccount;
		test.stoptest();
		TestLeads = [select Status from Lead where Account__c = :TestAccount.Id limit 1];
		System.Assert(TestLeads[0].Status == 'Contacted');
	}
	
	static testMethod void UpdateLeadWithManyCoworkers(){
		LeadSync_AsyncApex.firstTrigger = false; // Keep the triggers from starting future methods
		Account TestAccount = new Account(Status__c = 'Targeted', Name = 'Test');
		insert TestAccount;
		List<Lead> TestLeads = new List<Lead>();
		for(integer j = 0; j<3;j++){
			for(integer i=0;i<100;i++){
				TestLeads.add( new Lead(Account__c = TestAccount.Id, Company = 'Test', LastName='Test '+i ,Status = 'Targeted'));
			}
			insert TestLeads;
			TestLeads.clear();
		}
		Lead TestLead = [select Status from Lead where Account__c = :TestAccount.Id limit 1];
		TestLead.Status = 'Contacted';
		test.starttest();
		LeadSync_AsyncApex.firstTrigger = true;
		update TestLead;
		test.stoptest();
		TestAccount = [select Status__c from Account where Id = :TestAccount.Id];
		System.Assert(TestAccount.Status__c == 'Contacted');
	}
	
	static testMethod void UpdateTwoLeadsSameAccount(){
		LeadSync_AsyncApex.firstTrigger = false; // Keep the triggers from starting future methods
		Account TestAccount = new Account(Status__c = 'Targeted', Name = 'Test');
		insert TestAccount;
		List<Lead> TestLeads = new List<Lead>();
		for(integer i=0;i<3;i++){
			TestLeads.add( new Lead(Account__c = TestAccount.Id, Company = 'Test', LastName='Test '+i ,Status = 'Targeted'));
		}
		insert TestLeads;
		TestLeads = [select Status from Lead where Account__c = :TestAccount.Id];
		for(Lead TestLead : TestLeads){
				TestLead.Status = 'Contacted';
		}
		test.starttest();
		LeadSync_AsyncApex.firstTrigger = true;
		Lead TestLead1 = TestLeads[0];
		Lead TestLead2 = TestLeads[1];
		update TestLead1;
		update TestLead2;
		test.stoptest();
		TestAccount = [select Status__c from Account where Id = :TestAccount.Id];
		System.Assert(TestAccount.Status__c == 'Contacted');
	}
}